<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        * {
            margin: 0;
            padding: 0;
        }
    </style>
</head>

<body>
    <canvas id="canvas"></canvas>
</body>
<!-- Line -->
<script id="TextureVertexShader" type="x-shader/x-vertex">
    attribute vec4 a_Position;
    attribute vec2 a_Pin;
    uniform float u_PointSize;
    uniform mat4 u_ModelM4;
    uniform mat4 u_PvM4;
    varying vec2 v_Pin;
    void main(){
        gl_Position = u_PvM4 * u_ModelM4 * a_Position;
        gl_PointSize = u_PointSize;
        v_Pin = a_Pin;
    }
</script>
<script id="TextureFragmentShader" type="x-shader/x-fragment">
    precision mediump float;
    uniform sampler2D u_Sampler;
    varying vec2 v_Pin;
    void main(){
        vec4 a = texture2D(u_Sampler, v_Pin);
        if(a.r <= 0.2){
            a = vec4(0,0,0,0);
        }
        gl_FragColor = a;
    }
</script>
<script id="TextureFragmentShader1" type="x-shader/x-fragment">
    precision mediump float;
    uniform sampler2D u_Sampler;
    varying vec2 v_Pin;
    void main(){
        vec4 a = texture2D(u_Sampler, v_Pin);
        if(a.r <= 0.1){
            a = vec4(0,0,0,0);
        }else{
            a = vec4(1,1,0,0.1);
        }
        gl_FragColor = a;
    }
</script>
<script type="module">
    import { Matrix4, Vector3, Color, OrthographicCamera, PerspectiveCamera, Spherical } from '../js/three.module.js';
    import { CreateProgram, imgPromise } from '../js/Utils.js';
    import lib from '../js/ThreeLib.js';
    import CameraController from '../js/CameraController.js'
    import Geo from '../js/Poly/Geo.js'
    import Mat from '../js/Poly/Mat.js'
    import Obj3D from '../js/Poly/Obj3D.js'
    import Scene from '../js/Poly/Scene.js'



    //#region gl
    const canvas = document.getElementById("canvas");
    canvas.width = window.innerWidth;
    canvas.height = window.innerHeight - 4;

    const gl = canvas.getContext("webgl", { antialias: true, });
    //开始背景遮挡
    // gl.enable(gl.DEPTH_TEST);
    gl.enable(gl.BLEND);
    gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
    gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, true);
    //#endregion



    const scene = new Scene({ gl: gl });

    const pvM4 = new Matrix4();
    const modelM4 = new Matrix4();
    const moveM4 = new Matrix4();
    const images = [];
    const imgArr = LoadImage();
    let [maxX, maxY] = [0, 0.4];

    let startX = 0;
    let endX = 0;
    let offset = 0;

    const imgConfigOfPosi = [
        [0, 0], [0, 0], [0, 0], [0, 0], [-0.3, -0.5],
        [0.2, 0.7], [0, 0], [0, 0], [0, -0.2], [-0.2, -1],
        [0.3, -0.3], [-0.4, -0.05], [0.3, -1], [0.5, -0.3], [0, 0],
        [-1.1, 0], [1.2, 0],
    ];
    const imgConfigOfScale = [
        [1, 1], [1, 1], [1, 1], [1, 1], [0.5, 0.5],
        [1, 1], [1, 1], [1, 1], [0.7, 0.7], [1, 1],
        [0.5, 0.5], [1, 1], [1, 1], [0.7, 0.7], [1, 1],
        [1, 1], [1, 1],
    ];

    const imgConfigOfMove = [
        0.95, 0.97, 0.99, 0.93, 0.9,
        0.6, 0.9, 0.9, 0.75, 0.92,
        0.8, 0.85, 0.96, 0.85, 0.94,
        1.0, 1.0

    ];



    canvas.addEventListener('mouseover', function (event) {
        startX = event.clientX;
        //计算出与两边的比例

        //到右canvas.width - startX
    });
    canvas.addEventListener('mousemove', function (event) {
        // endX = event.clientX;
        if (startX < event.clientX) {
            offset = -1 * (event.clientX - startX) / (canvas.width - startX)
        } else {
            offset = (startX - event.clientX) / startX
        }
        setModelM4(offset);
        draw();
    });
    canvas.addEventListener('mouseout', function (event) {
        startX = 0;
    });






    Promise.all(imgArr).then((image) => {

        image.forEach((u, index) => {
            let positionArr = getPositionArr(getImageInGlPosition(u, index));
            createObj3D(u, positionArr);
        });

        setModelM4(0);
        draw();

    });


    //获取图片在gl中应该显示的位置
    function getImageInGlPosition(img, index) {
        //1080/281
        //对应gl中 1/0.4
        const { width, height } = img;
        const [maxW, maxH] = [1080 / 2, 281 / 2];
        const w = width / 2 / maxW;
        const h = height / 2 / maxH;
        if (maxX < w) {
            maxX = w / 1.8;
        }
        return [w * 1 * imgConfigOfScale[index][0], h * 0.4 * imgConfigOfScale[index][1]];
    }
    //获取Position的数组
    function getPositionArr([w, h]) {
        return [
            -w, h,
            -w, -h,
            w, -h,
            w, h
        ];
    }
    //创建图片
    function createObj3D(img, positionArr) {
        let textureProgram;
        if (img.name.split('_')[1] == 7 || img.name.split('_')[1] == 8) {
            textureProgram = CreateProgram(gl,
                document.querySelector('#TextureVertexShader').innerText,
                document.querySelector('#TextureFragmentShader1').innerText);
        } else {
            textureProgram = CreateProgram(gl,
                document.querySelector('#TextureVertexShader').innerText,
                document.querySelector('#TextureFragmentShader').innerText);
        }

        let obj = new Obj3D({
            geo: new Geo({
                data: {
                    'a_Position': {
                        size: 2, array: new Float32Array(positionArr)
                    },
                    'a_Pin': {
                        size: 2, array: new Float32Array([0, 1, 0, 0, 1, 0, 1, 1])
                    },
                },
                element: {
                    array: new Uint8Array([0, 1, 2, 0, 2, 3])
                }
            }),
            mat: new Mat({
                program: textureProgram,
                mode: ['TRIANGLES'],
                data: {
                    'u_PvM4': { type: 'uniformMatrix4fv', value: pvM4.elements },
                    'u_ModelM4': { type: 'uniformMatrix4fv', value: modelM4.elements },
                },
                maps: {
                    'u_Sampler': { image: img, WRAP_W: gl.LINEAR, WRAP_H: gl.LINEAR },
                }
            }),
        });

        scene.add(obj);
    }
    //加载图片
    function LoadImage(count = 17) {
        let arr = [];
        for (let i = 1; i <= count; i += 1) {
            let img = new Image();
            img.src = `./Images/${i}.webp`;
            img.name = 'a_' + i;
            arr.push(imgPromise(img));
            images.push(img);
        }
        return arr;
    }



    function setModelM4(offset) {
        moveM4.setPosition(offset * (maxX - 1), 0, 0)
    }


    //渲染
    function draw() {
        for (let i = 0; i < scene.children.length; i++) {

            let [x, y] = getImagePosi(i);
            let m4 = new Matrix4(
                1, 0, 0, x,
                0, 1, 0, y,
                0, 0, 1, 0,
                0, 0, 0, 1
            );
            let move = moveM4.clone();
            move.elements[12] *= imgConfigOfMove[i];
            if (i == 6) {
                move.elements[12] = Math.sin(imgConfigOfMove[i] * offset * 5 % 200) / 2
            }
            if (i == 7) {
                move.elements[12] = Math.sin(imgConfigOfMove[i] * offset * 5 % 200) / -2
            }

            m4.multiply(move);

            scene.children[i].setUniform('u_ModelM4', {
                value: m4.elements
            });
        }
        scene.draw();
    }


    function getImagePosi(imgIndex) {
        const [x, y] = [imgConfigOfPosi[imgIndex][0], imgConfigOfPosi[imgIndex][1]];
        const node = scene.children[imgIndex].geo.data['a_Position'].array;
        const [x1, y1] = [node[3 * 2] - node[0 * 2], node[0 * 2 + 1] - node[1 * 2 + 1]];
        let [x2, y2] = [0, 0];
        if (Math.abs(x) == 1) {
            if (x > 0) {
                x2 = maxX - x1 / 2;
            } else {
                //吸附左边
                x2 = -maxX + x1 / 2;
            }
        } else {
            x2 = x * maxX;
        }
        if (Math.abs(y) == 1) {
            if (y > 0) {
                y2 = maxY - y1 / 2;
            } else {
                y2 = -maxY + y1 / 2;
            }
        } else {
            y2 = y * maxY;
        }
        return [x2, y2];
    }
</script>

</html>